﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Collections;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
using System.Runtime.Serialization.Formatters;

namespace RDPServer
{
    public partial class frmServerMain : Form
    {
        public frmServerMain()
        {
            InitializeComponent();
            this.FormClosed += new FormClosedEventHandler(frmServerMain_FormClosed);
            this.StartPosition = FormStartPosition.CenterScreen;
            this.WindowState = FormWindowState.Minimized;
            this.ShowInTaskbar = false;

            RDPRemoteObject.FaxBusiness.FaxSendedEvent += new RDPCommon.FaxEventHandler(OnFaxSended);
            RDPRemoteObject.UserLogin.UserLoginEvent += new RDPCommon.UserLoginEventHandler(OnUserLogin);
            RDPRemoteObject.UserLogin.UserLogoutEvent += new RDPCommon.UserLogoutEventHandler(OnUserLogout);
            SetServerState(0); //启动服务 
            SetOnlineUsers();
        }

        public void OnUserLogin(RDPCommon.Client.ClinetInfo clientInfo)
        {
            if (this.listView1.InvokeRequired)
            {
                this.listView1.Invoke(new SetMsgHandler(AddMsg), clientInfo);
            }
            else
            {
                AddMsg(clientInfo);
            }

            if (this.treeView1.InvokeRequired)
            {
                this.treeView1.Invoke(new UpdateTreeDelegate(UpdateTree), new object[] { 0, clientInfo });
            }
            else
            {
                UpdateTree(0, clientInfo);
            }
        }

        public void OnUserLogout(RDPCommon.Client.ClinetInfo clientInfo)
        {
            if (this.listView1.InvokeRequired)
            {
                this.listView1.Invoke(new SetMsgHandler(RemoveMsg), clientInfo);
            }
            else
            {
                RemoveMsg(clientInfo);
            }

            if (this.treeView1.InvokeRequired)
            {
                this.treeView1.Invoke(new UpdateTreeDelegate(UpdateTree), new object[] { 1, clientInfo });
            }
            else
            {
                UpdateTree(1, clientInfo);
            }
        }

        delegate void UpdateTreeDelegate(int flag, RDPCommon.Client.ClinetInfo clientInfo);

        void UpdateTree(int flag, RDPCommon.Client.ClinetInfo clientInfo) //0 Add 1 Remove
        {
            TreeNode tn = null;
            if (flag == 0)
            {
                tn = new TreeNode(clientInfo.UserCode);
                tn.Name = clientInfo.SessionID;
                tn.Tag = clientInfo;                
                this.treeView1.Nodes.Add(tn);
            }
            else if (flag == 1)
            {
                TreeNode[] tns = this.treeView1.Nodes.Find(clientInfo.SessionID, true);
                if (tns.Length > 0)
                    this.treeView1.Nodes.Remove(tns[0]);
            }
        }

        delegate void SetMsgHandler(RDPCommon.Client.ClinetInfo clientInfo);

        void AddMsg(RDPCommon.Client.ClinetInfo clientInfo)
        {
            ListViewItem li = new ListViewItem(new string[] { 
                clientInfo.UserCode,
                clientInfo.Case,
                clientInfo.DB,
                clientInfo.DeviceIP,
                clientInfo.LoginDateTime });
            li.Name = clientInfo.SessionID;
            this.listView1.Items.Add(li);
            SetOnlineUsers();
        }

        void RemoveMsg(RDPCommon.Client.ClinetInfo clientInfo)
        {
            ListViewItem[] lis = this.listView1.Items.Find(clientInfo.SessionID, false);
            if (lis.Length > 0)
                this.listView1.Items.Remove(lis[0]);
            SetOnlineUsers();
        }

        private void frmServerMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            int iOnLine = RDPRemoteObject.UserLogin.GetActiveUsers().Count;
            if (iOnLine > 0)
            {
                if (
                    RDPCommon.Util.ShowConfigDialog(
                        String.Format("该服务存在 {0} 个活动客户端联接,您是否确认退出?\r\n\r\n您的强行退出将会造成客户端未保存的数据丢失.",
                    iOnLine)
                        )
                    != DialogResult.Yes)
                {
                    e.Cancel = true;
                    return;
                }
            }
        }

        private void tmiGBXX_Click(object sender, EventArgs e)
        {
            ToolStripItem si = sender as ToolStripItem;
            int _x = si.Bounds.X;
            int _y = si.Bounds.Y;
            ToolStrip ts = si.GetCurrentParent() as ToolStrip;
            _x += ts.PointToScreen(new Point(0, 0)).X;
            _y += ts.PointToScreen(new Point(0, 0)).Y;
            int _w = si.Width;
            int _h = si.Height;
            Rectangle _loc = new Rectangle(_x, _y, _w, _h);

            Tool.frmChat.ShowChat(this, _loc);
        }

        private void tsbTC_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void tmiStart_Click(object sender, EventArgs e)
        {
            SetServerState(0);
        }

        private void tmiPause_Click(object sender, EventArgs e)
        {
            SetServerState(1);
        }

        void SetServerState(int flag) //0启动 1暂停
        {
            if (flag == 0)
            {
                RDPRemoteObject.UserLogin.Servicing = true;
                this.statusStrip1.Items[0].Text = "服务已启动";
                this.statusStrip1.Items[0].ForeColor = System.Drawing.Color.Green;
            }
            else if (flag == 1)
            {
                RDPRemoteObject.UserLogin.Servicing = false;
                this.statusStrip1.Items[0].Text = "服务已暂停";
                this.statusStrip1.Items[0].ForeColor = System.Drawing.Color.Red;
            }
            this.tsbStart.Enabled = flag == 1;
            this.tmiStart.Enabled = flag == 1;

            this.tmiPause.Enabled = flag == 0;
            this.tsbPause.Enabled = flag == 0;
        }

        void frmServerMain_FormClosed(object sender, FormClosedEventArgs e)
        {
            RDPRemoteObject.FaxBusiness.FaxSendedEvent -= new RDPCommon.FaxEventHandler(OnFaxSended);
            RDPRemoteObject.UserLogin.UserLoginEvent -= new RDPCommon.UserLoginEventHandler(OnUserLogin);
            RDPRemoteObject.UserLogin.UserLogoutEvent -= new RDPCommon.UserLogoutEventHandler(OnUserLogout);
        }

        private void tmiRefreshUsers_Click(object sender, EventArgs e)
        {
            try
            {
                RDPCommon.frmWaiting.ShowWaiting();

                FillActiveUsersDelegate ff = new FillActiveUsersDelegate(FillActiveUsers);
                ff.BeginInvoke(new AsyncCallback(ss), null);

                this.toolStrip1.Enabled = false;
                this.menuStrip1.Enabled = false;
                this.ControlBox = false;
            }
            catch (Exception ex)
            {
                RDPCommon.frmWaiting.CloseWaiting();
                RDPCommon.Util.ShowExceptionDialog(ex);

                SetFormState();
            }
        }

        delegate void FillActiveUsersDelegate();

        void ss(IAsyncResult asy)
        {
            RDPCommon.frmWaiting.CloseWaiting();
            if (this.InvokeRequired)
                this.Invoke(new SetFormStateDeleagte(SetFormState));
            else
                SetFormState();

        }

        delegate void SetFormStateDeleagte();

        void SetFormState()
        {
            this.toolStrip1.Enabled = true;
            this.menuStrip1.Enabled = true;
            this.ControlBox = true;
        }

        delegate void ClearTreeItemDelegate();
        delegate void AddTreeItemDelegate(ListViewItem tn);
        void ClearTreeItem()
        {
            this.listView1.Items.Clear();
        }

        void AddTreeItem(ListViewItem tn)
        {
            this.listView1.Items.Add(tn);
        }

        void FillActiveUsers()
        {
            if (this.listView1.InvokeRequired)
                this.listView1.Invoke(new ClearTreeItemDelegate(ClearTreeItem));
            else
                ClearTreeItem();

            Dictionary<string, RDPCommon.Client.ClinetInfo> dic = RDPRemoteObject.UserLogin.GetActiveUsers();
            Dictionary<string, RDPCommon.Client.ClinetInfo> dicOff = new Dictionary<string, RDPCommon.Client.ClinetInfo>();
            object[] rtn = null;
            ListViewItem li = null;
            foreach (KeyValuePair<string, RDPCommon.Client.ClinetInfo> kp in dic)
            {
                rtn = RDPCommon.Server.ServerTool.OnlineTest(new object[] { kp.Value });
                if (rtn != null && Convert.ToInt32(rtn[0]) == 0)
                {
                    li = new ListViewItem(new string[] { 
                kp.Value.UserCode, 
                kp.Value.Case ,
                kp.Value.DB,
                kp.Value.DeviceIP,
                kp.Value.LoginDateTime });
                    li.Name = kp.Value.SessionID;
                    if (this.listView1.InvokeRequired)
                        this.listView1.Invoke(new AddTreeItemDelegate(AddTreeItem), li);
                    else
                        AddTreeItem(li);
                }
                else
                {
                    dicOff.Add(kp.Value.SessionID, kp.Value);
                }
            }
            foreach (KeyValuePair<string, RDPCommon.Client.ClinetInfo> kp in dicOff)
            {
                RDPRemoteObject.UserLogin.ClearClientRegInfo(kp.Value);
            }
            SetOnlineUsers();
        }

        void SetOnlineUsers()
        {
            this.statusStrip1.Items[1].Text = String.Format("在线用户:{0}", this.listView1.Items.Count);
        }

        private void CaseMgrCToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Tool.frmCaseMgr f = new Tool.frmCaseMgr();
            f.ShowDialog();
        }

        private void DBMgrDToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Tool.frmDBMgr f = new Tool.frmDBMgr();
            f.ShowDialog();
        }

        private void notifyIcon1_Click(object sender, EventArgs e)
        {
            if (this.WindowState == System.Windows.Forms.FormWindowState.Minimized)
            {
                this.Visible = true;
                this.WindowState = System.Windows.Forms.FormWindowState.Normal;
                this.notifyIcon1.Visible = false;
                this.ShowInTaskbar = true;
            }   
        }

        private void frmServerMain_SizeChanged(object sender, EventArgs e)
        {
            if (this.WindowState == System.Windows.Forms.FormWindowState.Minimized)
            {
                this.Hide();
                this.notifyIcon1.Visible = true;
                this.ShowInTaskbar = false;
            }
        }

        public void OnFaxSended(string msg)
        {
            if (!this.ckbRecvMsg.Checked) //是否接收消息
                return;

            if (this.textBox2.InvokeRequired)
            {
                this.textBox2.Invoke(new SendedMsgHandler(SetMessage), new object[] { 0, msg });
            }
            else
            {
                SetMessage(0, msg);
            }
        }

        delegate void SendedMsgHandler(int flag, string msg);

        void SetMessage(int flag, string msg) //0 接收的消息 1 发出的消息
        {
            msg = msg.Replace(System.Environment.NewLine, "<br>");
            RDPServer.Tool.frmChat.m_Msg.Add(msg);
            if (flag == 0)
                this.textBox2.DocumentText += "<div style='color:red;'>" + msg + "</div>";
            else if (flag == 1)
                this.textBox2.DocumentText += "<div style='color:blue;'>" + msg + "</div>";
            this.Activate();
        }

        bool CtrlDown = false;
        private void textBox1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Control && e.KeyCode == Keys.Enter)
            {
                CtrlDown = true;
                btnSend_Click(null, null);
            }
        }

        private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (CtrlDown)
                e.Handled = true;
        }

        private void textBox1_KeyUp(object sender, KeyEventArgs e)
        {
            CtrlDown = e.Control;
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            try
            {
                ArrayList al = new ArrayList();
                foreach (TreeNode tn in this.treeView1.Nodes)
                {
                    if (tn.Checked)
                        al.Add((tn.Tag as RDPCommon.Client.ClinetInfo).SessionID);
                }
                if (al.Count == 0)
                {
                    RDPCommon.Util.ShowWarningDialog("请至少选择一项接收客户端.");
                    return;
                }

                if (String.IsNullOrEmpty(this.textBox1.Text))
                {
                    RDPCommon.Util.ShowWarningDialog("发送信息不可为空.");
                    this.textBox1.Focus();
                    return;
                }
                string msg = "";
                msg = System.DateTime.Now.ToString("yyyy-MM-dd hh:MM:ss") + " (" + RDPCommon.Util.GetIpAddress() + " 服务端)";
                msg += System.Environment.NewLine;
                msg += this.textBox1.Text.Trim();
                msg += System.Environment.NewLine;
                msg += System.Environment.NewLine;
                object[] rtn = RDPCommon.Server.ServerTool.BroadCastingInfo(
                    new object[] { al.ToArray(), msg });
                if (rtn != null && Convert.ToInt32(rtn[0]) != 0)
                {
                    Exception ex = rtn[1] as Exception;
                    throw ex;
                }
                else
                {
                    SetMessage(1, msg);
                    this.textBox1.Focus();
                    this.textBox1.Text = "";
                }
            }
            catch (Exception ex)
            {
                RDPCommon.Util.ShowExceptionDialog(ex);
            }
        }

        private void checkBox1_Click(object sender, EventArgs e)
        {
            CheckBox ckb = sender as CheckBox;
            foreach (TreeNode tn in this.treeView1.Nodes)
            {
                tn.Checked = ckb.Checked;
            }
        }

        private void textBox2_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            this.textBox2.Document.Window.Parent.ScrollTo(0, System.Int32.MaxValue);   
        }

        private void btnClear_Click(object sender, EventArgs e)
        {            
            this.textBox2.DocumentText = "";
        }

        
    }
}
